package me.silentdoer.socketdebugger.gui;

import com.jfoenix.controls.JFXDecorator;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Cursor;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Callback;
import me.silentdoer.socketdebugger.constant.ApplicationConstants;
import me.silentdoer.socketdebugger.model.TreeItemMappingData;
import me.silentdoer.socketdebugger.model.TreeItemTypeEnum;

import java.util.Objects;
import java.util.Optional;

/**
 * @author wlq
 * @version 1.0.0
 * @since 19-9-14 上午10:28
 */
public class SocketDebuggerApplication extends Application {

	private Stage appWindow;

	private Scene appScene;

	private Parent appRootPane;

	@Override
	public void init() throws Exception {
		super.init();
	}

	@Override
	public void start(Stage primaryStage) throws Exception {

		this.appWindow = primaryStage;
		SplitPane rootPane = new SplitPane();
		rootPane.setOrientation(Orientation.VERTICAL);
		this.appRootPane = rootPane;
		//this.appScene = new Scene(this.appRootPane);

		JFXDecorator decorator = new JFXDecorator(primaryStage, this.appRootPane);
		decorator.setCustomMaximize(true);
		decorator.setTitle("Socket-Debugger");
		Image favicon = new Image(ApplicationConstants.APP_FAVICON_NAME);
		ImageView imageView = new ImageView(favicon);
		imageView.setFitWidth(24);
		imageView.setFitHeight(24);
		decorator.setGraphic(imageView);
		decorator.setOnCloseButtonAction(() -> {
			Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "确定要退出吗？", ButtonType.OK, ButtonType.CANCEL);
			alert.initOwner(primaryStage);
			Optional<ButtonType> result = alert.showAndWait();
			if (result.isPresent() && ButtonType.OK.equals(result.get())) {
				System.exit(0);
			}
		});
		//region set primary window
		this.appScene = new Scene(decorator);
		primaryStage.setScene(this.appScene);
		//primaryStage.setScene(this.appScene);
		primaryStage.setTitle("Socket-Debugger");
		primaryStage.setWidth(800);
		primaryStage.setHeight(600);
		this.appRootPane.setStyle("-fx-font-family: '思源宋体 CN'");
		/*primaryStage.setMaxWidth(1320);
		primaryStage.setMaxHeight(990);*/
		primaryStage.setMinWidth(600);
		primaryStage.setMinHeight(450);
		primaryStage.getIcons().add(favicon);

		/*primaryStage.maximizedProperty().addListener((observable, oldValue, newValue) -> {
			System.out.println("是否执行老师放假了疯狂");
			Rectangle2D screenBounds = Screen.getPrimary().getVisualBounds();
			if (newValue) {
				primaryStage.setX((screenBounds.getWidth() - primaryStage.getMaxWidth()) / 2);
			} else {
				primaryStage.setX((screenBounds.getWidth() - primaryStage.getMinWidth()) / 2);
			}
		});*/
		//endregion set primary window

		FlowPane topPane = new FlowPane();
		topPaneInit(topPane);
		rootPane.getItems().add(topPane);

		SplitPane bottomPane = new SplitPane();
		//bottomPane.setOrientation(Orientation.HORIZONTAL);
		BorderPane leftPane = new BorderPane();
		leftPaneInit(leftPane);
		bottomPane.getItems().add(leftPane);

		TitledPane brPane = new TitledPane();
		/*brPane.setLayoutX(0);
		brPane.setLayoutY(0);*/
		brPane.setCursor(Cursor.HAND);
		brPane.setCollapsible(false);
		brPane.setAnimated(false);
		brPane.setText("操作区");
		brPane.prefHeightProperty().bind(bottomPane.heightProperty());
		brPane.setBackground(new Background(new BackgroundFill(Color.color(0.3, 0.5 ,0.3), null, null)));
		//brPane.setStyle("-fx-background-color: #8FBC8F");
		VBox vBox = new VBox();
		vBox.setOpacity(1);
		vBox.setAlignment(Pos.TOP_CENTER);
		vBox.setSpacing(10.0);
		//brPane.setContent(vBox);
		bottomPane.getItems().add(brPane);
		bottomPane.setDividerPosition(0, 0.2);

		rootPane.getItems().add(bottomPane);
		// show
		primaryStage.show();
	}

	@Override
	public void stop() throws Exception {
		super.stop();
	}

	private void topPaneInit(FlowPane topPane) {
		topPane.setStyle("-fx-background-color: #BC8F8F");
		topPane.setMinHeight(Region.USE_PREF_SIZE);
		topPane.setMaxHeight(Region.USE_PREF_SIZE);
		topPane.setHgap(5);
		/*BorderPane upPane = new BorderPane();
		MenuBar menuBar = new MenuBar();
		Menu about = new Menu("About");
		Menu help = new Menu("Help");

		MenuItem aboutMe = new MenuItem("About Me");*/

		/*menuBar.getMenus().addAll(about, help);
		about.getItems().add(aboutMe);
		upPane.setTop(menuBar);*/

		Button btnAdd = new Button("添加");
		btnAdd.prefHeightProperty().bind(topPane.heightProperty());
		Button btnDel = new Button("删除");
		btnDel.setStyle("-fx-font-family: '思源宋体 CN SemiBold'");
		btnDel.prefHeightProperty().bind(topPane.heightProperty());
		Button btnStop = new Button("停止");
		btnStop.prefHeightProperty().bind(topPane.heightProperty());
		//ButtonBar.setButtonData(btnAdd, ButtonBar.ButtonData.APPLY);

		/*((BorderPane) topPane).setTop(upPane);*/
		topPane.getChildren().addAll(btnAdd, btnDel, btnStop);
	}

	private void leftPaneInit(Pane leftPane) {
		leftPane.setPrefWidth(300);
		leftPane.setMaxWidth(400);
		leftPane.setMinWidth(100);
		leftPane.setStyle("-fx-background-color: #CDBE70");

		TreeView<TreeItemMappingData> treeView = new TreeView<>();
		TreeItemMappingData rootNodeData = TreeItemMappingData.builder().text(TreeItemTypeEnum.ROOT.name())
				.type(TreeItemTypeEnum.ROOT).mappingData(null).build();
		TreeItem<TreeItemMappingData> rootItem = new TreeItem<>(rootNodeData);
		treeView.setRoot(rootItem);
		// hide root node
		treeView.setShowRoot(false);
		treeView.setPadding(Insets.EMPTY);
		treeView.setOpaqueInsets(Insets.EMPTY);
		treeView.setTooltip(new Tooltip("Socket服务面板"));

		TreeItem<TreeItemMappingData> tcpServer01 = new TreeItem<>();
		TreeItemMappingData tcpServerNode1Data = TreeItemMappingData.builder().text("192.168.1.100[8888]")
				.type(TreeItemTypeEnum.SERVER).mappingData(null).build();
		tcpServer01.setValue(tcpServerNode1Data);

		TreeItemMappingData tcpServerTypeNodeData = TreeItemMappingData.builder().text("TCP Server")
				.type(TreeItemTypeEnum.SERVER_TYPE).mappingData(null).build();
		TreeItem<TreeItemMappingData> tcpServerNode = new TreeItem<>(tcpServerTypeNodeData);
		tcpServerNode.getChildren().add(tcpServer01);

		TreeItemMappingData udpServerTypeNodeData = TreeItemMappingData.builder().text("UDP Server")
				.type(TreeItemTypeEnum.SERVER_TYPE).mappingData(null).build();
		TreeItem<TreeItemMappingData> udpServerNode = new TreeItem<>(udpServerTypeNodeData);
		rootItem.getChildren().add(tcpServerNode);
		rootItem.getChildren().add(udpServerNode);

		treeView.setOnMouseClicked(new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent event) {
				if (event.getClickCount() == 1 && event.getButton() == MouseButton.SECONDARY) {
					/*if (event.isConsumed()) {
						return;
					}*/
					TreeItem<TreeItemMappingData> selectedItem = treeView.getSelectionModel().getSelectedItem();
					if (Objects.isNull(selectedItem)) {
						return;
					}
					if (TreeItemTypeEnum.SERVER_TYPE.equals(selectedItem.getValue().getType())) {
						ContextMenu serverTypeMenu = new ContextMenu();
						MenuItem item1 = new MenuItem("添加服务");
						item1.setOnAction(new EventHandler<ActionEvent>() {
							@Override
							public void handle(ActionEvent event) {
								TreeItemMappingData tcpServerNode2Data = TreeItemMappingData.builder()
										.text("192.88.9.11[3333]").type(TreeItemTypeEnum.SERVER).mappingData(null).build();
								TreeItem<TreeItemMappingData> server = new TreeItem<>(tcpServerNode2Data);
								selectedItem.getChildren().add(server);
							}
						});
						serverTypeMenu.getItems().addAll(item1);
						serverTypeMenu.show(SocketDebuggerApplication.this.appWindow, event.getScreenX(), event.getScreenY());
						//serverTypeMenu.show(treeView, event.getScreenX(), event.getScreenY());
						//treeView.setContextMenu(serverTypeMenu);
					} else if (TreeItemTypeEnum.SERVER.equals(selectedItem.getValue().getType())) {
						ContextMenu serverMenu = new ContextMenu();
						MenuItem item2 = new MenuItem("修改服务");
						item2.setOnAction(new EventHandler<ActionEvent>() {
							@Override
							public void handle(ActionEvent event) {
								TreeItem<TreeItemMappingData> selectedItem = treeView.getSelectionModel().getSelectedItem();
								TreeItemMappingData selectedItemValue = selectedItem.getValue();
								if (TreeItemTypeEnum.SERVER.equals(selectedItemValue.getType())
										&& selectedItem.getChildren().isEmpty()) {
									selectedItemValue.setText("88.99.11.30[2222]");
									treeView.refresh();
								}
							}
						});
						MenuItem item3 = new MenuItem("断开所有");
						serverMenu.getItems().addAll(item2, item3);
						serverMenu.show(SocketDebuggerApplication.this.appWindow, event.getScreenX(), event.getScreenY());
						//serverMenu.show(treeView, event.getScreenX(), event.getScreenY());
						//treeView.setContextMenu(serverMenu);
					}
					//event.consume();
				}
			}
		});

		/*treeView.setEditable(false);
		Callback<TreeView<String>, TreeCell<String>> callback = TextFieldTreeCell.forTreeView(new StringConverter<String>() {
			@Override
			public String toString(String object) {
				return null;
			}

			@Override
			public String fromString(String string) {
				return null;
			}

		});*/

		treeView.setCellFactory(new Callback<TreeView<TreeItemMappingData>, TreeCell<TreeItemMappingData>>() {

			@Override
			public TreeCell<TreeItemMappingData> call(TreeView<TreeItemMappingData> param) {

				return new TreeCell<TreeItemMappingData>() {

					/**
					 *
					 * @param item item 新的item值【但是updateItem会被调用多次，后面this.getItem()将不会是null】
					 * @param empty empty 表示item是否是null
					 */
					@Override
					protected void updateItem(TreeItemMappingData item, boolean empty) {
						super.updateItem(item, empty);
						this.setBackground(new Background(new BackgroundFill(Color.color(0.3, 0.5 ,0.3), null, null)));
						System.out.println("是否相等" + (item == this.getItem()) + "##" + item + "##" + this.getItem() + "##" + empty);
						if (Objects.nonNull(this.getItem())) {
							String transformedVal = this.getItem() + "mmm";

						}
						if (Objects.nonNull(this.getItem())) {

							//treeView.setContextMenu(serverTypeMenu);

							ImageView serverTypeImg = new ImageView("images/serverType.png");
							HBox hBox = new HBox();
							hBox.setAlignment(Pos.CENTER_LEFT);
							if (TreeItemTypeEnum.SERVER_TYPE.equals(this.getTreeItem().getValue().getType())) {
								//serverTypeImg = new ImageView("images/serverType.png");
							} else if (TreeItemTypeEnum.SERVER.equals(this.getTreeItem().getValue().getType())) {
								serverTypeImg = new ImageView("images/server.png");
							}
							serverTypeImg.setFitWidth(24);
							serverTypeImg.setFitHeight(24);
							serverTypeImg.setPreserveRatio(true);
							hBox.getChildren().addAll(serverTypeImg, new Label(this.getItem().getText()));

							TreeItem<TreeItemMappingData> treeItem = this.getTreeItem();
							hBox.setOnMouseClicked(event -> {
								// 点一次鼠标左键
								if (event.getClickCount() == 1 && event.getButton() == MouseButton.PRIMARY) {
									if (treeItem.isExpanded()) {
										treeItem.setExpanded(false);
									} else {
										treeItem.setExpanded(true);
									}
								}
							});
							this.setGraphic(hBox);
						} else {
							this.setGraphic(null);
						}
					}
				};
			}
		});
		//treeView.setCellFactory(CheckBoxTreeCell.forTreeView());

		((BorderPane) leftPane).setCenter(treeView);
	}
}
